package com.renaud.tvSpy;


import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import com.renaud.tvSpy.graphicsTool.Capter;
import com.renaud.tvSpy.graphicsTool.JImageBuffer;
import com.renaud.tvSpy.graphicsTool.VideoDevice;
import com.renaud.tvSpy.menu.MyMenu;






public class View{


	
	
	private JFrame frame;
	private JImageBuffer backBuffer;
	private VideoDevice activeDevice;
	private Offscreen offscreen;
	private int largeur;
	private int hauteur;
	private float scale;
	private Timer timer;
	private Capter capter;
	private int fps;
	private RepaintTask task;
	private boolean reading;

	
	public View(float scale,int fps){
		this.scale = scale;
		this.fps = fps;
		
		this.frame = new JFrame();
		this.frame.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
		
		this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);	
	}

	
	public void setActiveDevice(VideoDevice device){
		this.activeDevice = device;
		// calcul taille de l'offscreen
		this.largeur = (int) (device.getLargeur() * this.scale);
		this.hauteur = (int) (device.getHauteur() * this.scale);
		
		// on remove l'ancien offscreen
		if(this.offscreen!=null) this.frame.remove(this.offscreen);
		
		// on recré le nouveau
		List<JImageBuffer> backbuffer = new ArrayList<JImageBuffer>();
		this.backBuffer =  new JImageBuffer(new Color(255,0,255),this.largeur,this.hauteur);
		this.backBuffer.clean();
		backbuffer.add(0,this.backBuffer);
		this.offscreen = new Offscreen(backbuffer);
		this.offscreen.setPreferredSize(new Dimension(this.largeur,this.hauteur));
		this.frame.add(this.offscreen);
		
		// on crée une loupe
		Loupe loupe = new Loupe(this.backBuffer,scale,(int)(0.5*this.largeur),(int) (0.5*this.hauteur));
		
		// on créer le robot de capture
		this.capter = new Capter(device);
		
		
		// on valide l'affichage
		this.offscreen.validate();
		this.frame.validate();
		this.frame.pack();
		this.frame.setVisible(true);
		this.frame.setResizable(false);
		this.frame.setAlwaysOnTop(true);
	
		this.repaint();
		
		
		
		// on (re)initialise le thread d'affichage
		if(this.timer == null){
			// on crée la tache de dessin
			this.task = new RepaintTask(this,this.capter,this.backBuffer,this.scale,loupe);
			GlobalScreen.getInstance().addNativeKeyListener(this.task);
			this.firstStart();
		}else{
			this.task.setCapter(this.capter);
			this.task.setBackbuffer(this.backBuffer);
			this.task.setLoupe(loupe);
		}
		
	}
	
	
	
	public JFrame getFrame() {
		return frame;
	}


	public void repaint(){
		this.frame.repaint();
	}
	
	



	private void firstStart(){
		this.timer = new Timer();
		final RepaintTask rt = this.task;
		
		TimerTask task = new TimerTask() {
			@Override
			public void run() {
				rt.run();
			}
		};
		
		
		
		this.timer.schedule(task, 0, (long) (1000.0/this.fps));
		
		
		// reading
		this.reading = true;
		this.task.startReading();
	}
	
	
	public void startReading(){
		this.reading = true;
		this.task.startReading();
	}
	
	public void stopReading(){
		this.reading = false;
		this.task.stopReading();
	}
	

	public VideoDevice getActiveDevice() {
		return activeDevice;
	}


	public boolean isReading() {
		return reading;
	}


	public void setReading(boolean reading) {
		this.reading = reading;
	}


	
	
	
	
	public static void main(String[] args) {
		 try {
			GlobalScreen.registerNativeHook();
		} catch (NativeHookException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		 
		float scale = 0.6f;
		int fps = 30;
		
		
		List<VideoDevice> devices = VideoDevice.getDevices();
		
		
		View view = new View(scale,fps);
		
		MyMenu menu = new MyMenu(view);
		
		for(VideoDevice vd : devices) menu.addDevice(vd);
	
		view.getFrame().setJMenuBar(menu.getMenu());
		view.setActiveDevice(devices.get(0));
		
	}
}
